package com.tonyodev.fetch2fileserver;

import ohos.aafwk.ability.DataAbilityHelper;
import ohos.app.Context;
import ohos.utils.net.Uri;

import com.tonyodev.fetch2core.FetchCoreUtils;
import com.tonyodev.fetch2core.FileResource;
import com.tonyodev.fetch2core.InputResourceWrapper;
import com.tonyodev.fetch2core.server.FileRequest;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class FileResolver {
    private Context appContext;
    private DataAbilityHelper contentResolver;


    public FileResolver(Context context) {
        this.appContext = context;
        this.contentResolver = DataAbilityHelper.creator(appContext);
    }

    public Context getAppContext() {
        return appContext;
    }

    /**
     * getContentResolver
     *
     * @return 返回数据库操作helper类
     */
    public DataAbilityHelper getContentResolver() {
        return contentResolver;
    }

    /**
     * Returns the [InputResourceWrapper] for the catalog file
     */

    /**
     * Returns the [InputResourceWrapper] for the catalog file
     *
     * @param catalog 字符串数据
     * @param request 文件请求封装类
     * @param fileResource 文件资源信息
     * @return 输入流封装
     */
    public InputResourceWrapper getCatalogInputWrapper(byte[] catalog, FileRequest request, FileResource fileResource) {
        return new InputResourceWrapper() {
            private ByteArrayInputStream inputStream = new ByteArrayInputStream(catalog, (int) request.getRangeStart(), (int) fileResource.getLength());

            @Override
            public void close() throws IOException {
                inputStream.close();
            }

            @Override
            public int read(byte[] byteArray, int offSet, int length) throws IOException {
                return inputStream.read(byteArray, offSet, length);
            }

            @Override
            public void setReadOffset(long offset) throws IOException {
                inputStream.skip(offset);
            }
        };
    }

    /**
     * getInputWrapper
     *
     * @param fileResource 文件资源信息
     * @return 输入流封装
     * @throws FileNotFoundException
     */
    public InputResourceWrapper getInputWrapper(FileResource fileResource) throws FileNotFoundException {

        return FetchCoreUtils.isUriPath(fileResource.getFile()) ? getUriInputResourceWrapper(fileResource) : getFileInputResourceWrapper(fileResource);
    }

    private InputResourceWrapper getUriInputResourceWrapper(FileResource fileResource) {
        InputResourceWrapper inputResourceWrapper = null;
        Uri fileUri = Uri.parse(fileResource.getFile());
        try {
            if (fileUri.getScheme().equals("content")) {
                String str = String.valueOf(fileUri).replace("content:", "dataability:/");
                FileDescriptor parcelFileDescriptor = contentResolver.openFile(Uri.parse(str), "w");
                if (parcelFileDescriptor == null) {
                    throw new FileNotFoundException("$fileUri $FILE_NOT_FOUND");
                } else {
                    inputResourceWrapper = createUriInputResourceWrapper(new FileInputStream(parcelFileDescriptor), parcelFileDescriptor);
                }
            } else if (fileUri.getScheme().equals("file")) {
                File file = new File(fileUri.getDecodedPath());
                if (file.exists() && file.canWrite()) {
                    inputResourceWrapper = createUriInputResourceWrapper(new FileInputStream(file), null);
                } else {
                    FileDescriptor parcelFileDescriptor = contentResolver.openFile(fileUri, "w");
                    if (parcelFileDescriptor == null) {
                        throw new FileNotFoundException("$fileUri $FILE_NOT_FOUND");
                    } else {
                        inputResourceWrapper = createUriInputResourceWrapper(new FileInputStream(parcelFileDescriptor), parcelFileDescriptor);
                    }
                }
            } else {
                throw new FileNotFoundException("$fileUri $FILE_NOT_FOUND");
            }
        } catch (Exception e) {
            System.out.println("错误信息==============>" + e.getMessage());
        }
        return inputResourceWrapper;
    }

    private InputResourceWrapper createUriInputResourceWrapper(FileInputStream fileInputStream, FileDescriptor FfileDescriptor) {
        return new InputResourceWrapper() {
            private FileInputStream wrapperFileInputStream = fileInputStream;

            @Override
            public int read(byte[] byteArray, int offSet, int length) throws IOException {
                return wrapperFileInputStream.read(byteArray, offSet, length);
            }

            @Override
            public void setReadOffset(long offset) throws IOException {
                wrapperFileInputStream.getChannel().position(offset);
            }

            @Override
            public void close() throws IOException {
                wrapperFileInputStream.close();
            }
        };
    }

    private InputResourceWrapper getFileInputResourceWrapper(FileResource fileResource) throws FileNotFoundException {
        return new InputResourceWrapper() {

            private RandomAccessFile randomAccessFile = new RandomAccessFile(fileResource.getFile(), "r");

            @Override
            public int read(byte[] byteArray, int offSet, int length) throws IOException {
                return randomAccessFile.read(byteArray, offSet, length);
            }

            @Override
            public void setReadOffset(long offset) throws IOException {
                randomAccessFile.getChannel().position(offset);
            }

            @Override
            public void close() throws IOException {
                randomAccessFile.close();
            }
        };
    }
}
